﻿using System;
using System.Collections.Generic;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Cms.Application.Admin.Presenters;
using Cms.Application.Admin.Views;
using Cms.Domain;
using Cms.Domain.Comparers;
using Cms.Web.Framework.Controls;
using iLib.Web.UI;
using Page = Cms.Domain.Page;
using SortDirection = Cms.Domain.SortDirection;

namespace Cms.Web.UI.Admin
{
    public partial class Explorer : AdminPage, IExplorerView
    {
        private ExplorerPresenter _presenter;

        public override string HelpPage
        {
            get { return "dialogs/explorer.aspx"; }
        }

        #region IExplorerView Members

        public string ContextTranslationFile
        {
            get { return "Admin/Translations/Explorer.xml"; }
        }
        
        public void SetFolders(string domain, IList<Folder> folders, string localeCode)
        {
            string html = "<span id=\"domain\"";
            if (SelectedFolderID == -1)
            {
                html += " class=\"selected\"";
            }
            html += "><img src=\"Admin/Img/icons/house.png\" /><span>" + domain + "</span></span>";
            RenderFolders(ref html, folders);
            litFolders.Text = html;
            /*
            This is the resulting structure:
            <ul>
                <li>
                    <a href="#"><img src="Admin/Img/treenodeClosed.gif" /></a><span id="A"><img src="Admin/Img/icons/folder.png" /><span>Aaaaaa</span></span>
                    <ul>
                        <li>
                            <a href="#"><img src="Admin/Img/treenodeClosed.gif" /></a><span id="F"><img src="Admin/Img/icons/folder.png" /><span>Ffffffffff</span></span>
                            <ul>
                                <li>
                                    <img src="Admin/Img/tp.gif" width="6" height="9" /><span id="G"><img src="Admin/Img/icons/folder.png" /><span>Ggggggggg</span></span>
                                </li>
                                <li>
                                    <img src="Admin/Img/tp.gif" width="6" height="9" /><span id="H"><img src="Admin/Img/icons/folder.png" /><span>Hhhhhhhhhh</span></span>
                                </li>
                            </ul>
                        </li>
                    </ul>
                </li>
                <li>
                    <img src="Admin/Img/tp.gif" width="6" height="9" /><span id="B"><img src="Admin/Img/icons/folder.png" /><span>Bbbbbbbb</span></span>
                </li>
            </ul>
            */
        }

        public void SetPages(IList<Page> pages)
        {
            rpPages.DataSource = pages;
            rpPages.DataBind();
            pnlNoPages.Visible = rpPages.Items.Count == 0;
        }
        
        public int SelectedFolderID
        {
            get { return hidSelectedFolderID.Value == "domain" ? -1 : int.Parse(hidSelectedFolderID.Value.Substring(1)); }
            set { hidSelectedFolderID.Value = value == -1 ? "domain" : "F" + value; }
        }
        
        public void DisplayCreateMasterTemplateAlert()
        {
            hlNewPage.Attributes.Add(
                "onclick", 
                "cms.Dialogs.Alert(null, '" +
                                    GetText(this, "CreateTemplateAlertHeader") + "', '" +
                                    GetText(this, "CreateMasterTemplateAlertMessage") + "', '" +
                                    GetText(this, "CreateTemplateAlertOK") +
                                    "'); return false;");
        }

        public void DisplayCreateDetailTemplateAlert()
        {
            hlNewPage.Attributes.Add(
                "onclick", 
                "cms.Dialogs.Alert(null, '" +
                                    GetText(this, "CreateTemplateAlertHeader") + "', '" +
                                    GetText(this, "CreateDetailTemplateAlertMessage") + "', '" +
                                    GetText(this, "CreateTemplateAlertOK") +
                                    "'); return false;");
        }
        
        public int LocaleID
        {
            get { return -1; } //iLib.Web.UI.QueryString.GetInt32ID("localeid");
        }
        
        public void ExplorerAddFolderNotAllowed()
        {
            hlNewFolder.Visible = false;
        }

        #endregion

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            _presenter = new ExplorerPresenter(this);
            HeadingText = GetText(this, "Heading");
            if (!Page.IsPostBack)
            {
                _presenter.Initialize();
                HeadingIcon = litIcon.Text;
            }
            lbDeleteFolder.OnClientClick = "return cms.Dialogs.ConfirmLinkButton(this, " +
                                               "function (status) { " +
                                                   "if (status == 'ok') " +
                                                        "cms.Lists.ShowPaneOverlay('folderPaneOverlay');" +
                                                   "else " +
                                                        "cms.Lists.HidePaneOverlays(); " +
                                               "}, " +
                                               "'" + GetText(this, "DeleteHeader") + "', " +
                                               "'" + GetText(this, "DeleteFolderMessage") + "', " +
                                               "'" + GetText(this, "DeleteOK") + "', " +
                                               "'" + GetText(this, "DeleteCancel") + "', " +
                                               "true, " +
                                               "cms.Lists.CurrentName);";
            lbDeletePage.OnClientClick = "return cms.Dialogs.ConfirmLinkButton(this, " +
                                             "function (status) { " +
                                                 "if (status == 'ok') " +
                                                        "cms.Lists.ShowPaneOverlay('pagePaneOverlay');" +
                                                 "else " +
                                                        "cms.Lists.HidePaneOverlays(); " +
                                             "}, " +
                                             "'" + GetText(this, "DeleteHeader") + "', " +
                                             "'" + GetText(this, "DeletePageMessage") + "', " +
                                             "'" + GetText(this, "DeleteOK") + "', " +
                                             "'" + GetText(this, "DeleteCancel") + "', " +
                                             "true, " +
                                             "cms.Lists.CurrentName);";
            string confirmDragScript = "function confirmDrag(draggedElement, dropzoneElement) { " +
                                            "var message = '" + GetText(this, "DragWarningMessage") + "';" +
                                            "message = message.replace(/\\[\\[draggedElement\\]\\]/gi, cms.Utils.GetInnerText(draggedElement));" +
                                            "message = message.replace(/\\[\\[dropzoneElement\\]\\]/gi, cms.Utils.GetInnerText(dropzoneElement));" +
                                            "cms.Dialogs.Confirm(function (status) { " +
                                                "if (status == 'ok') { " +
                                                    "cms.Lists.ShowPaneOverlay('pagePaneOverlay');" +
                                                    "cms.Lists.ShowPaneOverlay('folderPaneOverlay');" +
                                                    "__doPostBack('ctl00$body$lbDragEnd', '');" +
                                                "} " +
                                                "else " +
                                                    "cms.Lists.HidePaneOverlays(); " +
                                            "}, " +
                                            "'" + GetText(this, "DragWarningHeader") + "', " +
                                            "message, " +
                                            "'" + GetText(this, "DragWarningOK") + "', " +
                                            "'" + GetText(this, "DragWarningCancel") + "', " +
                                            "true);" +
                                        "}";
            this.ClientScript.RegisterClientScriptBlock(this.GetType(), "confirmDragScript", confirmDragScript, true);
        }

        protected void lbDragEnd_Click(object sender, EventArgs e)
        {
            if (hidDropzoneID.Value == string.Empty)
            {
                return;
            }
            _presenter.Move(hidDraggedID.Value, hidDropzoneID.Value);
            UpdateFolderPane();
            if (hidDraggedID.Value.Substring(0, 1) == "P" || hidDraggedID.Value.Substring(0, 1) == "A")
            {
                UpdatePagePane();
            }
        }

        protected void btnSelectFolder_Click(object sender, EventArgs e)
        {
            _presenter.OpenFolder();
            UpdatePagePane();
        }

        protected void btnToggleFolder_Click(object sender, EventArgs e)
        {
            _presenter.ToggleFolder(int.Parse(hidToggleFolderId.Value));
            UpdateFolderPane();
        }

        protected void lbDeleteFolder_Click(object sender, EventArgs e)
        {
            _presenter.DeleteFolder(int.Parse(hidDeleteFolderID.Value.Substring(1)));
            UpdateFolderPane();
            UpdatePagePane();
        }
        
        protected void lbDeletePage_Click(object sender, EventArgs e)
        {
            _presenter.DeletePage(int.Parse(hidSelectedPageID.Value.Substring(1)));
            UpdatePagePane();
        }
        
        protected void lbPreviewPage_Click(object sender, EventArgs e)
        {
            string url = _presenter.GetPagePreviewUrl(int.Parse(hidSelectedPageID.Value.Substring(1)));
            Response.Redirect(url);
        }
        
        protected void rpPages_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem)
            {
                return;
            }
            var p = (Page)e.Item.DataItem;
            var litID = (Literal)e.Item.FindControl("litID");
            var litName = (Literal)e.Item.FindControl("litName");
            var litFilename = (Literal)e.Item.FindControl("litFilename");
            var litMasterTemplate = (Literal)e.Item.FindControl("litMasterTemplate");
            var litDetailTemplate = (Literal)e.Item.FindControl("litDetailTemplate");
            var litCategories = (Literal)e.Item.FindControl("litCategories");
            var litUserGroups = (Literal)e.Item.FindControl("litUserGroups");
            var litPageID = (Literal)e.Item.FindControl("litPageID");
            var imgPage = (HtmlImage)e.Item.FindControl("imgPage");
            litID.Text = @"<span id=""";
            litID.Text += p is ApplicationPage ? "A" : "P";
            litID.Text += p.ID + @""">";
            litName.Text = p.Name;
            litFilename.Text = p.Filename;
            if (p.Filename.ToLower() == "default.aspx")
            {
                litName.Text = "<strong>" + litName.Text + "</strong>";
                litFilename.Text = "<strong>" + litFilename.Text + "</strong>";
            }
            litMasterTemplate.Text = p.MasterTemplate.Name;
            litDetailTemplate.Text = p.DetailTemplate.Name;
            litPageID.Text = p.ID.ToString();
            imgPage.Src = p is ApplicationPage ? "Admin/Img/icons/page_code.png" : "Admin/Img/icons/page.png";
            string categories = string.Empty;
            var allCategories = new List<Category>(p.GetAllCategories());
            allCategories.Sort(new CategoryNameComparer(SortDirection.Ascending));
            foreach (Category c in allCategories)
            {
                if (p.Folder != null && c.ContainsFolder(p.Folder))
                {
                    categories += "<span class=\"inheritedCategory\">" + c.Name + "</span>";
                }
                else
                {
                    categories += c.Name;
                }
                categories += ", ";
            }
            categories = categories.TrimEnd(", ".ToCharArray());
            litCategories.Text = categories;
            string requiredUserGroups = string.Empty;
            var allRequiredUserGroups = new List<UserGroup>(p.GetRequiredUserGroups());
            allRequiredUserGroups.Sort(new UserGroupNameComparer(SortDirection.Ascending));
            foreach (UserGroup group in allRequiredUserGroups)
            {
                if (p.Folder != null && group.AllowsFolder(p.Folder))
                {
                    requiredUserGroups += "<span class=\"inheritedCategory\">" + group.Name + "</span>";
                }
                else
                {
                    requiredUserGroups += group.Name;
                }
                requiredUserGroups += ", ";
            }
            requiredUserGroups = requiredUserGroups.TrimEnd(", ".ToCharArray());
            if (requiredUserGroups == string.Empty)
            {
                requiredUserGroups = GetText(this, "AllowAccessForEveryone");
            }
            litUserGroups.Text = requiredUserGroups;
        }
        
        private void UpdateFolderPane()
        {
            upnlFolders.Update();
            ClientScriptProxy.Current.RegisterStartupScript(pnlFolderActions, GetType(), "initFolderList", "initFolderList();", true);
        }

        private void UpdatePagePane()
        {
            upnlPages.Update();
            ClientScriptProxy.Current.RegisterStartupScript(pnlPageActions, GetType(), "initPageList", "initPageList();", true);
        }

        private void RenderFolders(ref string html, ICollection<Folder> folders)
        {
            if (folders.Count == 0)
            {
                return;
            }
            html += "<ul>";
            foreach (Folder folder in folders)
            {
                html += "<li>";
                if (folder.SubFolders.Count == 0)
                {
                    html += "<a href=\"javascript:void();\" class=\"empty\"></a>";
                }
                else
                {
                    html += "<a href=\"javascript:void();\" id=\"T" + folder.ID + "\" class=\"";
                    html += _presenter.IsFolderClosed(folder.ID) ? "closed" : "open";
                    html += "\"></a>";
                }
                html += "<span id=\"F" + folder.ID + "\"";
                if (SelectedFolderID == folder.ID)
                {
                    html += " class=\"selected\"";
                }
                html += "><img src=\"Admin/Img/icons/folder.png\" /><span>" + folder.Name + "</span></span>";
                html += "</li>";
                if (!_presenter.IsFolderClosed(folder.ID))
                {
                    RenderFolders(ref html, folder.SubFolders);
                }
            }
            html += "</ul>";
        }
    }
}